<template>
<div id="css2dLabel">

</div>
</template>

<script setup lang='ts'>
import { onMounted } from 'vue'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
import { CSS2DRenderer, CSS2DObject } from 'three/examples/jsm/renderers/CSS2DRenderer'
import { GUI } from 'three/examples/jsm/libs/lil-gui.module.min.js'
import { AxesHelper, Clock, DirectionalLight, Mesh, MeshPhongMaterial, PerspectiveCamera, Scene, SphereGeometry, TextureLoader, Vector2, WebGLRenderer } from 'three'

let gui:GUI, camera:PerspectiveCamera, scene:Scene, renderer:WebGLRenderer, labelRenderer:CSS2DRenderer

const layers = {
    'Toggle Name': () => {
        camera.layers.toggle(0)
    },
    'Toggle Mass': () => {
        camera.layers.toggle(1)
    },
    'Enable All': () => {
        camera.layers.enableAll()
    },
    'Disable All': () => {
        camera.layers.disableAll()
    }
}

const clock = new Clock()
const textureLoader = new TextureLoader()

let moon:Mesh

const init = () => {
    const EARTH_RADIUS = 1
    const MOON_RADIUS = 0.27

    camera = new PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 200)
    camera.position.set(10, 5, 20)
    camera.layers.enableAll()
    camera.layers.toggle(1)

    const scene = new Scene()

    const directLight = new DirectionalLight(0xffffff)
    directLight.position.set(0, 0, 1)
    directLight.layers.enableAll()
    scene.add(directLight)

    const axesHelper = new AxesHelper(10)
    axesHelper.layers.enableAll()
    scene.add(axesHelper)

    const earthGeometry = new SphereGeometry(EARTH_RADIUS, 16, 16)
    const earthMaterial = new MeshPhongMaterial({
        specular: 0x333333,
        shininess: 5,
        map: textureLoader.load('/textures/planets/earth_atmos_2048.jpg'),
        specularMap: textureLoader.load('/textures/planets/earth_specular_2048.jpg'),
        normalMap: textureLoader.load('/textures/planets/earth_normal_2048.jpg'),
        normalScale: new Vector2(0.85, 0.85)
    })
    const earth = new Mesh(earthGeometry, earthMaterial)
    scene.add(earth)

    const moonGeometry = new SphereGeometry(MOON_RADIUS, 16, 16)
    const moonMaterial = new MeshPhongMaterial({
        shininess: 5,
        map: textureLoader.load('/textures/planets/moon_1024.jpg')
    })
    moon = new Mesh(moonGeometry, moonMaterial)
    scene.add(moon)

    earth.layers.enableAll()
    moon.layers.enableAll()

    const earthDiv = document.createElement('div')
    earthDiv.className = 'label'
    earthDiv.textContent = '地球'
    earthDiv.style.marginTop = '-1em'
    const earthLabel = new CSS2DObject(earthDiv)
    earthLabel.position.set(0, EARTH_RADIUS, 0)
    earth.add(earthLabel)
    earthLabel.layers.set(0)

    const earthMassDiv = document.createElement('div')
    earthMassDiv.className = 'label'
    earthMassDiv.textContent = '5.97237e24千克'
    earthMassDiv.style.marginTop = '-1em'
    const earthMassLabel = new CSS2DObject(earthMassDiv)
    earthMassLabel.position.set(0, -2 * EARTH_RADIUS, 0)
    earth.add(earthMassLabel)
    earthMassLabel.layers.set(1)

    const moonDiv = document.createElement('div')
    moonDiv.className = 'label'
    moonDiv.textContent = '月球'
    moonDiv.style.marginTop = '-1em'
    const moonLabel = new CSS2DObject(moonDiv)
    moonLabel.position.set(0, MOON_RADIUS, 0)
    moon.add(moonLabel)
    moonLabel.layers.set(0)

    const moonMassDiv = document.createElement('div')
    moonMassDiv.className = 'label'
    moonMassDiv.textContent = '7.342e22千克'
    moonMassDiv.style.marginTop = '-1em'
    const moonMassLabel = new CSS2DObject(moonMassDiv)
    moonMassLabel.position.set(0, -2 * MOON_RADIUS, 0)
    moon.add(moonMassLabel)
    moonMassLabel.layers.set(1)

    renderer = new WebGLRenderer()
    renderer.setPixelRatio(window.devicePixelRatio)
    renderer.setSize(window.innerWidth, window.innerHeight)
    const css2dLabel:HTMLElement = document.querySelector('#css2dLabel') as HTMLElement
    console.log(css2dLabel)
    console.log(renderer.domElement, document.body)

    css2dLabel.append(renderer.domElement)

    labelRenderer = new CSS2DRenderer()
    labelRenderer.setSize(window.innerWidth, window.innerHeight)
    labelRenderer.domElement.style.position = 'absolute'
    labelRenderer.domElement.style.top = '0px'

    css2dLabel.append(labelRenderer.domElement)

    const controls = new OrbitControls(camera, labelRenderer.domElement)
    controls.minDistance = 5
    controls.maxDistance = 100

    window.addEventListener('resize', onWindowResize)
    initGui()
}
const onWindowResize = () => {
    camera.aspect = window.innerWidth / window.innerHeight
    camera.updateProjectionMatrix()
    renderer.setSize(window.innerWidth, window.innerHeight)
    labelRenderer.setSize(window.innerWidth, window.innerHeight)
}
const animate = () => {
    requestAnimationFrame(animate)
    const elapsed = clock.getElapsedTime()
    moon.position.set(Math.sin(elapsed) * 5, 0, Math.cos(elapsed) * 5)
    renderer.render(scene, camera)
    labelRenderer.render(scene, camera)
}

const initGui = () => {
    gui = new GUI()
    gui.add(layers, 'Toggle Name')
    gui.add(layers, 'Toggle Mass')
    gui.add(layers, 'Enable All')
    gui.add(layers, 'Disable All')
}
onMounted(() => {
    init()
    // animate()
})

// animate()
</script>

<style lang='scss' scoped>
.label {
    color: #fff;
    font-family: sans-serif;
    padding: 2px;
    background: rgba(0, 0, 0, 0.6);
}
</style>
